package com.sky.service.courier.impl;

import com.sky.dto.UserLoginDTO;
import com.sky.exception.*;
import com.sky.mapper.admin.OrderMapper;
import com.sky.mapper.courier.CourierMapper;
import com.sky.mapper.courier.CourierTradeOrderMapper;
import com.sky.pojo.Courier;
import com.sky.pojo.CourierTradeOrder;
import com.sky.pojo.Orders;
import com.sky.result.Result;
import com.sky.service.courier.CourierService;
import com.sky.vo.CourierTradeOrderDetailItemVO;
import com.sky.vo.CourierTradeOrderDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;

@Service
@Slf4j
public class CourierServiceImpl implements CourierService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CourierMapper courierMapper;

    @Autowired
    private CourierTradeOrderMapper courierTradeOrderMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Override
    public Result login(UserLoginDTO dto) {

        //验参
        if(dto==null){
            throw new ParameterIsNullException("缺少请求参数");
        }
        //获取验证码
        String key = "code:"+dto.getTelephone();
        String serverCode = redisTemplate.opsForValue().get(key).toString();
        if(StringUtils.isEmpty(serverCode)){
            throw new CodeExpiredException("验证码已过期,请重新发送");
        }
        //校对验证码
        if(!serverCode.equals(dto.getCode())){
            throw new CodeErrorException("验证码错误");
        }
        //获取快递员信息，返回给前端
        Courier courier = courierMapper.selectByTelephone(dto.getTelephone());
        if(courier==null){
            throw new CourierNotExistException("快递员不存在，请检查手机号");
        }

        return Result.success(courier);
    }

    @Override
    @Transactional
    public void reveivingOrder(Long courierId, Long tradeNo) {
        //本质：就是修改两张表的状态————一个订单表，一个运单表
        CourierTradeOrder courierTradeOrder = courierTradeOrderMapper.findTradeOrderByTradeNo(tradeNo);
        if(courierTradeOrder==null){
            throw  new BaseException("查无此单");
        }
        courierTradeOrderMapper.updateStatusByTradeNo(tradeNo,CourierTradeOrder.DELIVORING);
        //修改商家订单状态
        Orders orders = new Orders();
        orders.setStatus(Orders.TOBEPICKEDUP);
        orders.setNumber(courierTradeOrder.getOrderNumber());
        orderMapper.updateOrder(orders);
    }

    @Override
    public Courier findById(Long id) {
        return courierMapper.selectById(id);
    }

    @Override
    public CourierTradeOrderDetailVO findCourierMonthTradeOrderInfo(Long courierId, String date) throws ParseException {
        LocalDate lastDay = getLastDay(date);
        LocalDate firstDay = getFirstDay(date);
        //  运单平均配送时长  单位-分钟
        Double avgTime = courierTradeOrderMapper.ordersCompleteAvgTime(courierId,firstDay,lastDay.plusDays(1));
        log.info("平均{}",avgTime);
        //  异常取消的运单量
        Long cancelTotal = courierTradeOrderMapper.ordersCountByCourierIdAndDate(courierId,firstDay,lastDay.plusDays(1),CourierTradeOrder.CANCLE_TRADE);
        log.info("异常{}",cancelTotal);
        //  已完成运单单量
        Long completedCount = courierTradeOrderMapper.ordersCountByCourierIdAndDate(courierId,firstDay,lastDay.plusDays(1),CourierTradeOrder.TRADE_COMPLETE);
        log.info("已完成{}",completedCount);
        //  运单配送准时率
        Long onTimeCount = courierTradeOrderMapper.ordersCountByCourierIdAndDate(courierId,firstDay,lastDay.plusDays(1),null);
        log.info("准时{}",onTimeCount);
        Double onTimeRate = onTimeCount/(completedCount*1.0);
        log.info("准时率{}",onTimeRate);
        List<String> dateList = new ArrayList<>();
        while (!firstDay.isAfter(lastDay)){
            dateList.add(firstDay.toString());
            firstDay = firstDay.plusDays(1);
        }
        // 查询指定时间段内：每一天的完成订单数
        /**
         *  map格式：
         *      map.key是日期，  map.value是数量
         *  {
         *      "2023-11-23":12,
         *      "2023-11-24":13
         *  }
         */
        Map<String,Long> map1 = courierTradeOrderMapper.ordersCountByDateAndStatus(courierId,firstDay,lastDay.plusDays(1),dateList,CourierTradeOrder.TRADE_COMPLETE);
        // 查询指定时间段内：每一天的取消订单数
        Map<String,Long> map2 = courierTradeOrderMapper.ordersCountByDateAndStatus(courierId,firstDay,lastDay.plusDays(1),dateList,CourierTradeOrder.CANCLE_TRADE);
        List<CourierTradeOrderDetailItemVO> list = new ArrayList<>();
        for(String d:dateList){
            Long everyDayCompleteCount = map1.get(d); //当天完成的订单数
            Long everyDayCancelCount = map2.get(d);  //当天取消的订单数
            CourierTradeOrderDetailItemVO vo = CourierTradeOrderDetailItemVO.builder()
                    .tradeOrderDate(d)
                    .tradeOrdersCompleted(everyDayCompleteCount.intValue())
                    .tradeOrdersCancelled(everyDayCancelCount.intValue())
                    .build();
            list.add(vo);
        }
        //组装
        CourierTradeOrderDetailVO vo =CourierTradeOrderDetailVO.builder()
                .tradeOrderAverageDuration(avgTime)
                .tradeOrdersCancelled(cancelTotal.intValue())
                .tradeOrdersCompleted(completedCount.intValue())
                .tradOrderOnTimeRate(onTimeRate)
                .tradeOrderDetails(list)
                .build();

        return vo;
    }

    public LocalDate getFirstDay(String date) throws ParseException {
        SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM");
        Date days = sm.parse(date);
        // 获取前月的第一天
        Calendar cale = Calendar.getInstance();
        cale.setTime(days);
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        SimpleDateFormat sms = new SimpleDateFormat("yyyy-MM-dd");
        return LocalDate.parse(sms.format(cale.getTime()));
    }

    public LocalDate getLastDay(String date) throws ParseException {
        SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM");
        Date days = sm.parse(date);
        // 获取前月的最后一天
        Calendar cale = Calendar.getInstance();
        cale.setTime(days);
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        SimpleDateFormat sms = new SimpleDateFormat("yyyy-MM-dd");
        return LocalDate.parse(sms.format(cale.getTime()));
    }



//    public String getFirstDayOfMonth(int month) {
//        Calendar calendar = Calendar.getInstance();
//        // 设置月份
//        calendar.set(Calendar.MONTH, month - 1);
//        // 获取某月最小天数
//        int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
//        // 设置日历中月份的最小天数
//        calendar.set(Calendar.DAY_OF_MONTH, firstDay);
//        // 格式化日期
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        String firstDayDate = sdf.format(calendar.getTime());
//        return firstDayDate;
//
//    }
    /**
     * 获取当前月最后一天
     * @param month
     * @return
     */
   /* public String getLastDayOfMonth(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay=0;
        //2月的平年瑞年天数
        if(month==2) {
            lastDay = calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);
        }else {
            lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayDate = sdf.format(calendar.getTime());
        return lastDayDate;

    }*/
}